#include "TaskQue.hpp"
#include <mutex>

namespace wd
{
using std::unique_lock;

TaskQue::TaskQue(size_t cap)
:_taskCapacity(cap)
,_taskArr()
,_exitFlag(false)
,_mutex()
,_notEmpty()
,_notFull()
{

}  


void TaskQue::push(TaskPtr task){
    unique_lock<mutex> ul(_mutex);

    if(task == nullptr){
        return ;
    }

    while(full() &&!_exitFlag){
        _notFull.wait(ul);
    }    
    
    _taskArr.push(task);
    _notEmpty.notify_one();
}


TaskPtr TaskQue::pop(){
    unique_lock<mutex> ul(_mutex);

    while(empty() && !_exitFlag){
        _notEmpty.wait(ul);
    }

    if(_exitFlag && empty()){
        return nullptr;
    }
    
    TaskPtr temp = _taskArr.front();
    _taskArr.pop();
    _notFull.notify_one();
    return temp;
}


void TaskQue::wakeup(){
    _exitFlag = true;
    _notEmpty.notify_all();
}

bool TaskQue::empty(){
    return _taskArr.size() == 0;
}

bool TaskQue::full(){
    return _taskArr.size() == _taskCapacity;
}

}//end of namespace wd
